package com.example.demo.common.entity;

import com.example.demo.common.enums.ExceptionStatus;
import com.example.demo.common.enums.MessageStatus;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

@Data
@Accessors(chain = true)
@Slf4j
public class MsgInfo {
    private Boolean success;
    
    private Integer code;
    
    private String message;
    
    private Object data;
    
    private MsgInfo() {
    }
    
    public static MsgInfo ok() {
        MsgInfo msgInfo = new MsgInfo();
        msgInfo.setSuccess(true);
        msgInfo.setCode(MessageStatus.OK.value());
        msgInfo.setMessage(MessageStatus.OK.message());
        return msgInfo;
    }
    
    public static MsgInfo ok(Object data) {
        MsgInfo msgInfo = new MsgInfo();
        msgInfo.setSuccess(true);
        msgInfo.setData(data);
        msgInfo.setCode(MessageStatus.OK.value());
        msgInfo.setMessage(MessageStatus.OK.message());
        return msgInfo;
    }
    
    public static MsgInfo error() {
        MsgInfo msgInfo = new MsgInfo();
        msgInfo.setSuccess(false);
        msgInfo.setCode(MessageStatus.ERROR.value());
        msgInfo.setMessage(MessageStatus.ERROR.message());
        return msgInfo;
    }
    
    public static MsgInfo error(ExceptionStatus exceptionStatus) {
        MsgInfo msgInfo = new MsgInfo();
        msgInfo.setSuccess(false);
        msgInfo.setCode(exceptionStatus.value());
        msgInfo.setMessage(exceptionStatus.message());
        return msgInfo;
    }
    
    public MsgInfo data(Object data) {
        this.data = data;
        return this;
    }
    
    public MsgInfo code(Integer code) {
        this.code = code;
        return this;
    }
    
    public MsgInfo msg(String message) {
        this.message = message;
        return this;
    }
    
    public <T> T getData(Class<T> clazz) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            return mapper.convertValue(this.data, clazz);
        } catch (Exception e) {
            log.error("convert object error -->" + e.getMessage());
            return null;
        }
    }
    
    public <T> List<T> getList(Class<T> clazz) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            JavaType javaType = mapper.getTypeFactory().constructParametricType(ArrayList.class, clazz);
            return mapper.convertValue(this.data, javaType);
        } catch (Exception e) {
            log.error("convert List error -->" + e.getMessage());
            return null;
        }
        
    }
    
}
